unit EntradaDM;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ZDataset, ZSqlUpdate, ZSequence, MainDM, DB, QueryConditions, DataRecord;

type

  { TEntradaData }

  TEntradaData = class(TMainDataModule)
    ChequeDatasource: TDatasource;
    ChequeZQuery: TZQuery;
    ChequeZQuerydata_vencimento: TDateField;
    ChequeZQueryid_cheque: TLargeintField;
    ChequeZQueryid_cliente: TLargeintField;
    ChequeZQueryid_duplicata_pagar: TLargeintField;
    ChequeZQueryid_duplicata_receber: TLargeintField;
    ChequeZQueryid_entrada: TLargeintField;
    ChequeZQueryid_venda: TLargeintField;
    ChequeZQuerynota: TStringField;
    ChequeZQuerynumero_agencia: TStringField;
    ChequeZQuerynumero_banco: TStringField;
    ChequeZQuerynumero_cheque: TStringField;
    ChequeZQuerynumero_conta: TStringField;
    ChequeZQuerysituacao_cheque: TStringField;
    ChequeZQueryvalor: TFloatField;
    ChequeZSequence: TZSequence;
    ChequeZUpdate: TZUpdateSQL;
    CondicaoPagamentoDatasource: TDatasource;
    CondicaoPagamentoZQuery: TZQuery;
    CondicaoPagamentoZQuerydesc_condicao_pagamento: TStringField;
    CondicaoPagamentoZQueryid_condicao_pagamento: TLargeintField;
    CondicaoPagamentoZSequence: TZSequence;
    CondicaoPagamentoZUpdate: TZUpdateSQL;
    CondPagParcelaDatasource: TDatasource;
    CondPagParcelaZQuery: TZQuery;
    CondPagParcelaZQuerydias: TLongintField;
    CondPagParcelaZQueryid_condicao_pagamento: TLargeintField;
    CondPagParcelaZQueryparcela: TLargeintField;
    CondPagParcelaZQueryporcentagem: TFloatField;
    CondPagParcelaZUpdate: TZUpdateSQL;
    DuplicataPagarDatasource: TDatasource;
    DuplicataPagarZQuery: TZQuery;
    DuplicataPagarZQuerydata_pagamento: TDateField;
    DuplicataPagarZQuerydata_vencimento: TDateField;
    DuplicataPagarZQuerydesconto: TFloatField;
    DuplicataPagarZQueryid_duplicata_pagar: TLargeintField;
    DuplicataPagarZQueryid_entrada: TLargeintField;
    DuplicataPagarZQueryid_fornecedor: TLargeintField;
    DuplicataPagarZQueryjuros: TFloatField;
    DuplicataPagarZQuerynome_pessoa: TStringField;
    DuplicataPagarZQuerynota: TStringField;
    DuplicataPagarZQueryparcela: TLargeintField;
    DuplicataPagarZQuerystatus: TStringField;
    DuplicataPagarZQueryvalor: TFloatField;
    DuplicataPagarZQueryvalor_pago: TFloatField;
    DuplicataPagarZSequence: TZSequence;
    DuplicataPagarZUpdate: TZUpdateSQL;
    EntradaItensDatasource: TDatasource;
    EntradaDatasource: TDatasource;
    EntradaItensZQueryatualizar: TStringField;
    EntradaItensZQuerycodigo_barra: TStringField;
    EntradaItensZQuerydesc_produto: TStringField;
    EntradaItensZQueryid_entrada: TLargeintField;
    EntradaItensZQueryid_entrada_produto: TLargeintField;
    EntradaItensZQueryid_produto: TLargeintField;
    EntradaItensZQueryquantidade: TFloatField;
    EntradaItensZQuerysigla_unidade: TStringField;
    EntradaItensZQueryTotal: TFloatField;
    EntradaItensZQueryvalor: TFloatField;
    EntradaZQuery: TZQuery;
    EntradaZQuerycode: TStringField;
    EntradaZQuerydata_emissao: TDateField;
    EntradaZQuerydata_entrada: TDateTimeField;
    EntradaZQuerydescontos: TFloatField;
    EntradaZQuerydesc_cfop: TStringField;
    EntradaZQueryfrete: TFloatField;
    EntradaZQueryid_condicao_pagamento: TLargeintField;
    EntradaZQueryid_entrada: TLargeintField;
    EntradaZQueryid_fornecedor: TLargeintField;
    EntradaZQueryid_usuario: TLargeintField;
    EntradaZQuerynome_pessoa: TStringField;
    EntradaZQuerynumero_nf: TLongintField;
    EntradaZQueryoutras_despesas: TFloatField;
    EntradaZQueryserie_nf: TStringField;
    EntradaZQueryvalor: TFloatField;
    EntradaZQueryvalor_total: TFloatField;
    EntradaZSequence: TZSequence;
    EntradaZUpdate: TZUpdateSQL;
    EntradaItensZQuery: TZQuery;
    EntradaItensZSequence: TZSequence;
    EntradaItensZUpdate: TZUpdateSQL;
    AuxiliarZQuery: TZQuery;
    procedure DataModuleCreate(Sender: TObject);
    procedure EntradaItensZQueryCalcFields(DataSet: TDataSet);
    /// Abre o DataSet
    procedure OpenDataSet(); override;
    /// Fecha o DataSet
    procedure CloseDataSet(); override;
    /// Realiza busca
    /// @param(Condicoes são as condições para a busca)
    /// @param(Tabela é a tabela no banco de dados)
    procedure Search(Condicoes: TQueryConditions; Tabela: string); override;
    procedure EntradaAdicionaProduto(CodigoBarra: string; Quantidade: real;
      Valor: real);
    function BuscaProduto(CodigoBarra: string): TDataRecord;
    procedure EntradaRemoveProduto();
    procedure PagamentoEntrada();
    procedure FechaPagamentoEntrada();
    procedure CancelaPagamentoEntrada(IDEntrada:string);
    procedure GeraDuplicataPagar(IDEntrada: integer; Data: TDate;
      IDFornecedor: integer; IDCondicaoPagamento: integer; Total: real);
    function BuscaData(): string;
    procedure CancelaDuplicatas(IDEntrada:string);
    procedure LimpaItens();
  end;
var
  EntradaData: TEntradaData;

implementation

uses ConnectionDM;

procedure TEntradaData.DataModuleCreate(Sender: TObject);
begin
  MainDataSet := EntradaZQuery;
  EntradaItensZQuery.Open();
end;

procedure TEntradaData.EntradaItensZQueryCalcFields(DataSet: TDataSet);
begin
  //Na tabela Itens de Produtos possui um campo que é calculado
  EntradaItensZQueryTotal.Value :=
    EntradaItensZQueryvalor.AsFloat * EntradaItensZQueryquantidade.AsFloat;
 end;

procedure TEntradaData.OpenDataSet;
begin
  ConnectionData.EmptyQuery(EntradaZQuery, 'entrada');
end;

procedure TEntradaData.CloseDataSet;
begin
  EntradaZQuery.Close();
end;

procedure TEntradaData.Search(Condicoes: TQueryConditions; Tabela: string);
begin
  ConnectionData.OpenQueryConditions(EntradaZQuery, Tabela, Condicoes);
end;

procedure TEntradaData.EntradaAdicionaProduto(CodigoBarra: string;
  Quantidade: real; Valor: real);
var
  Data: TDataRecord;
begin
  //Chama o método Busca Produto utilizando o código de barras
  Data := EntradaData.BuscaProduto(CodigoBarra);
  //Verifica se a quantidade que quer comprar é maior que a quantidade em estoque
  if Data <> nil then begin
    with AuxiliarZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('UPDATE produto');
      SQL.Add('SET quantidade=quantidade+:quantidade');
      SQL.Add('where codigo_barra =:codigo_barra;');
      ParamByName('codigo_barra').AsString := CodigoBarra;
      ParamByName('quantidade').AsFloat := Quantidade;
      ExecSQL();
    end;
    with EntradaItensZQuery do begin
      Insert();
      FieldByName('id_produto').AsString := Data.getValue('id_produto');
      FieldByName('codigo_barra').AsString := CodigoBarra;
      FieldByName('desc_produto').AsString := Data.getValue('desc_produto');
      FieldByName('valor').AsFloat := Valor;
      FieldByName('quantidade').AsFloat := Quantidade;
      Post();
    end;
    EntradaZQuery.Edit();
    //Fazer  o calculo primeiro na tabela
    EntradaZQuery.FieldByName('valor_total').AsFloat :=
      EntradaZQuery.FieldByName('valor_total').AsFloat + (Valor * Quantidade);
    EntradaZQuery.Post();
  end else begin
    ShowMessage('Produto Inexistente!');
  end;
end;


function TEntradaData.BuscaProduto(CodigoBarra: string): TDataRecord;
var
  Data: TDataRecord;
begin
  //Data := nil;
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT * FROM produto ');
    SQL.Add('WHERE codigo_barra=:codigo_barra');
    ParamByName('codigo_barra').AsString := CodigoBarra;
    Open();
    if RecordCount > 0 then begin
      Data := TDataRecord.Create;
      Data.ReadFromDataSet(AuxiliarZQuery);
      Result := Data;
    end else begin
      Result := nil;
    end;
  end;
end;

procedure TEntradaData.EntradaRemoveProduto();
begin
  if not (EntradaItensZQuery.BOF) and not (EntradaItensZQuery.EOF) then begin
    Edit();
    //!Fazer o calculo primeiro na tabela
    EntradaZQuery.FieldByName('valor_total').AsFloat :=
      EntradaZQuery.FieldByName('valor_total').AsFloat -
      ((EntradaItensZQuery.FieldByName('valor').AsFloat *
      EntradaItensZQuery.FieldByName('quantidade').AsFloat));
    Post();
    with AuxiliarZQuery do begin
      Close();
      SQL.Clear();
      SQL.Add('UPDATE produto');
      SQL.Add('SET quantidade=quantidade-:quantidade');
      SQL.Add('where codigo_barra =:codigo_barra;');
      ParamByName('codigo_barra').AsString :=
        EntradaItensZQuery.FieldByName('codigo_barra').AsString;
      ParamByName('quantidade').AsFloat :=
        EntradaItensZQuery.FieldByName('quantidade').AsFloat;
      ExecSQL();
    end;
    EntradaItensZQuery.Delete();
  end;
end;

procedure TEntradaData.PagamentoEntrada();
begin
  with EntradaZQuery do begin
    Open();
    Connection.StartTransaction();
    Edit();
  end;
end;

procedure TEntradaData.FechaPagamentoEntrada();
begin
  EntradaZQuery.Connection.Commit();
  EntradaZQuery.Refresh();
end;

procedure TEntradaData.CancelaPagamentoEntrada(IDEntrada: string);
begin
  CancelaDuplicatas(IDEntrada);
  EntradaZQuery.Connection.Rollback();
  EntradaZQuery.Refresh();
end;

procedure TEntradaData.GeraDuplicataPagar(IDEntrada: integer; Data: TDate;
  IDFornecedor: integer; IDCondicaoPagamento: integer; Total: real);
var
  IDPlanoConta:string;
begin
  //Busca o plano de conta Padrão
   with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('Select valor from configuracao where desc_configuracao=:desc');
    ParamByName('desc').AsString := 'PLANO_CONTA PADRAO PAGAMENTO DUPL';
    Open();
    if RecordCount > 0 then begin
      IDPlanoConta := FieldByName('valor').AsString;
    end;
   end;

  with DuplicataPagarZQuery do begin
    CancelaDuplicatas(IntToStr(IDEntrada));
    Close();
    SQL.Clear();
    SQL.Add('INSERT INTO duplicata_pagar(id_entrada,data_vencimento,id_fornecedor,valor,parcela,id_plano_conta)');
    SQL.add('SELECT :id_entrada,:data_vencimento+cpp.dias,:id_fornecedor,:valor*cpp.porcentagem/100,cpp.parcela,:id_plano_conta');
    SQL.Add('FROM condicao_pagamento_parcela as cpp');
    SQL.Add('WHERE cpp.id_condicao_pagamento=:id_condicao_pagamento');
    ParamByName('id_entrada').AsInteger := IDEntrada;
    ParamByName('data_vencimento').AsDate := Data;
    ParamByName('id_fornecedor').AsInteger := IDFornecedor;
    ParamByName('valor').AsFloat := Total;
    ParamByName('id_condicao_pagamento').AsInteger := IDCondicaoPagamento;
    ParamByName('id_plano_conta').AsString:=IDPlanoConta;
    ExecSQL();
    Close();
    SQL.Clear();
    SQL.Add('SELECT * FROM duplicata_pagar where id_entrada=:id_entrada');
    ParamByName('id_entrada').AsInteger := IDEntrada;
    Open();
    Edit();
  end;
end;

function TEntradaData.BuscaData(): string;
var
  Data: string;
begin
  with AuxiliarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('SELECT current_date as date');
    Open();
    Data := FieldByName('date').AsString;
    Result := Data;
  end;
end;

procedure TEntradaData.CancelaDuplicatas(IDEntrada: string);
begin
  with DuplicataPagarZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('DELETE FROM duplicata_pagar where id_entrada=:id_entrada');
    ParamByName('id_entrada').AsString := IDEntrada;
    ExecSQL();
  end;
end;

procedure TEntradaData.LimpaItens();
begin
   with EntradaItensZQuery do begin
    Close();
    SQL.Clear();
    SQL.Add('Select * FROM entrada_produto limit 0');
    Open();
  end;
end;



{ TEntradaData }


initialization
  {$I entradadm.lrs}

end.
